

#ifndef __CV_SOC_H__
#define __CV_SOC_H__


#include <stdint.h>

// cv1800b, big core.
#define CONFIG_PLIC_BASE        0x70000000


#include "csi_rv64_gcc.h"
#include "core_rv64.h"



#define CLK_DIV_BASE            0x03002000
#define PLL_G2_BASE             0x03002800
#define PLL_G6_BASE             0x03002900


#define CVI_GPIOA_BASE          0x03020000
#define CVI_GPIOB_BASE          0x03021000
#define CVI_GPIOC_BASE          0x03022000
#define CVI_GPIOD_BASE          0x03023000


#define CVI_TIMER0_BASE         0x030A0000
#define CVI_TIMER1_BASE         0x030A0014
#define CVI_TIMER2_BASE         0x030A0028
#define CVI_TIMER3_BASE         0x030A003c
#define CVI_TIMER4_BASE         0x030A0050
#define CVI_TIMER5_BASE         0x030A0064
#define CVI_TIMER6_BASE         0x030A0078
#define CVI_TIMER7_BASE         0x030A008C
#define CVI_TIMER_SUM_BASE      0x030A00A0


#define UART0_BASE              0x04140000
#define UART1_BASE              0x04150000
#define UART2_BASE              0x04160000
#define UART3_BASE              0x04170000


#define RTC_CTRL_BASE           0x05025000
#define RTC_CORE_BASE           0x05026000
#define RTC_MACRO_BASE          0x05026400
#define RTC_CORE_SRAM_BASE      0x05026800      /* 2K Bytes. */


#define SPINOR_BASE             0x10000000      /* 256M bytes */



typedef struct {

    union {
        __IM uint32_t RBR;          /* Offset: 0x000 (RO)  Receive Buffer */
        __OM uint32_t THR;          /* Offset: 0x000 (W)  Transmit Holding */
        __IOM uint32_t DLL;         /* Offset: 0x000 (R/W)  Divisor Latch Low byte */
    };

    union {
        __IOM uint32_t IER;         /* Offset: 0x004 (RO)  Interrupt Enable */
        __IOM uint32_t DLH;         /* Offset: 0x004 (WC)  Divisor Latch high byte */
    };

    union {
        __IM uint32_t IIR;          /* Offset: 0x008 (RO)  Interrupt Identification */
        __OM uint32_t FCR;          /* Offset: 0x008 (W)  FIFO Control */
    };

    __IOM uint32_t LCR;       		/* Offset: 0x00C (RW)  Line Control Register */
    __IOM uint32_t MCR;       		/* Offset: 0x010 (RW)  Modem Control Register */
    __IOM uint32_t LSR;       		/* Offset: 0x014 (RW)  Line Status Register */
    __IOM uint32_t MSR;       		/* Offset: 0x018 (RW)  Modem Status Register */
    __IOM uint32_t SCR;             /* Offset: 0x01C (RW)  Scratchpad Register */
    __IOM uint32_t LPDLL;           /* Offset: 0x020 (RW)  Low Power Divisor Latch (Low)  */
    __IOM uint32_t LPDLH;           /* Offset: 0x024 (RW)  Low Power Divisor Latch (High)  */
    uint32_t rsvd1[2];

    union {                         /* Offset: 0x030 (RO)  Interrupt Enable */
        __IOM uint32_t SRBR[16];
        __IOM uint32_t STHR[16];
    };

    __IOM uint32_t FAR;             /* Offset: 0x070 (RW)  Scratchpad Register */
    __IOM uint32_t TFR;             /* Offset: 0x074 (RW)  Scratchpad Register */
    __IOM uint32_t RFW;             /* Offset: 0x078 (RW)  Scratchpad Register */
    __IOM uint32_t USR;             /* Offset: 0x07C (RW)  Scratchpad Register */
    __IOM uint32_t TFL;             /* Offset: 0x080 (RW)  Transmit FIFO Level */
    __IOM uint32_t RFL;             /* Offset: 0x084 (RW)  Receive FIFO Level */
    __IOM uint32_t SRR;             /* Offset: 0x088 (RW)  Software Reset Register */
    
    __IOM uint32_t SRTS;            /* Offset: 0x08C (RW)  Shadow Request to Send */
    __IOM uint32_t SBCR;            /* Offset: 0x090 (RW)  Shadow Break Control */
    __IOM uint32_t SDMA;            /* Offset: 0x094 (RW)  Shadow DMA Mode */
    __IOM uint32_t SFE;             /* Offset: 0x098 (RW)  Shadow FIFO Enable */
    __IOM uint32_t SRT;             /* Offset: 0x09C (RW)  Shadow RCVR Trigger */
    __IOM uint32_t STET;            /* Offset: 0x0A0 (RW)  Shadow TX Empty Trigger */

} dw_uart_regs_t;





typedef struct {

    __IOM uint32_t CHIP_ID;      	/* Offset: 0x000 (R/W)   */
    __IOM uint32_t CONF_INFO;		/* Offset: 0x004 (R/W)   */
    __IOM uint32_t SYS_CTRL;		/* Offset: 0x008 (R/W)   */
    uint32_t rsvd1[16];

    __IOM uint32_t USB_PHY_CTRL;	/* Offset: 0x048 (R/W)   */
    uint32_t rsvd2[13];

    __IOM uint32_t GP_REG[4];		/* Offset: 0x080 (R/W)   */
	uint32_t rsvd3[9];

    __IOM uint32_t USB_ECO;			/* Offset: 0x0B4 (R/W)   */

} cv_top_regs_t;



typedef struct {

    __IOM uint32_t OUT;         /* Offset: 0x000 (R/W)  port data register  */
    __IOM uint32_t OPE;         /* Offset: 0x004 (R/W)  port out enable, 1-output  */
    uint32_t rsvd1[10];

    __IOM uint32_t INT_EN;      /* Offset: 0x030 (R/W)  interrupt enable  */
    __IOM uint32_t INT_MSK;     /* Offset: 0x034 (R/W)  interrupt mask, 1-mask  */
    __IOM uint32_t INT_LVL;     /* Offset: 0x038 (R/W)  interrupt level, 0-level, 1-edge  */
    __IOM uint32_t INT_POL;     /* Offset: 0x03C (R/W)  interrupt polarity  */
    __IM uint32_t INT_STS;      /* Offset: 0x040 (RO)   interrupt status */
    __IM uint32_t INT_RAW;      /* Offset: 0x044 (RO)   interrupt raw status*/

    __IOM uint32_t DEBOUNCE;    /* Offset: 0x048 (R/W)    */
    __IOM uint32_t INT_EOI;     /* Offset: 0x04C (R/W)  interrupt clear, end of interrupt, 1-Clear interrupt  */
    __IM uint32_t DIN;          /* Offset: 0x050 (RO)   data input  */
    uint32_t rsvd2[3];

    __IOM uint32_t SYNC;        /* Offset: 0x060 (R/W)  1-Synchronize to pclk_intr  */

} cvi_port_regs_t;




typedef struct {

    union {                             /* Offset: 0x000 (RW) */
        __IOM uint32_t BlkCnt32;        /* block count 32 */
        __IOM uint32_t SdmaAddr;        /* sdma system address */
    };

    __IOM uint16_t BlkSize;             /* Offset: 0x004 (RW) */
    __IOM uint16_t BlkCnt16;            /* Offset: 0x006 (RW) */

    __IOM uint32_t Argument;            /* Offset: 0x008 (RW) */
    
    __IOM uint16_t TransMode;           /* Offset: 0x00C (RW) */
    __IOM uint16_t Command;             /* Offset: 0x00E (RW) */
    
    __IOM uint32_t Response[4];         /* Offset: 0x010 (RW) */
    __IOM uint32_t BuffPort;            /* Offset: 0x020 (RW) */
    __IOM uint32_t PresState;           /* Offset: 0x024 (RW) */

    __IOM uint8_t HostCtrl1;            /* Offset: 0x028 (RW) */
    __IOM uint8_t PowerCtrl;            /* Offset: 0x029 (RW) */
    __IOM uint8_t BlockGap;             /* Offset: 0x02A (RW) */
    __IOM uint8_t WakeCtrl;             /* Offset: 0x02B (RW) */
    
    __IOM uint16_t ClockCtrl;           /* Offset: 0x02C (RW) */
    __IOM uint8_t TimeoutCtrl;          /* Offset: 0x02E (RW) */
    __IOM uint8_t SoftReset;            /* Offset: 0x02F (RW) */
    
    __IOM uint16_t NormalIntStatus;     /* Offset: 0x030 (RW) */
    __IOM uint16_t ErrorIntStatus;      /* Offset: 0x032 (RW) */
    __IOM uint16_t NormalIntEnable;     /* Offset: 0x034 (RW) */
    __IOM uint16_t ErrorIntEnable;      /* Offset: 0x036 (RW) */
    __IOM uint16_t NormalSigEnable;     /* Offset: 0x038 (RW) */
    __IOM uint16_t ErrorSigEnable;      /* Offset: 0x03A (RW) */
    __IOM uint16_t AutoCmdErrStatus;    /* Offset: 0x03C (RW) */
    __IOM uint16_t HostCtrl2;           /* Offset: 0x03E (RW) */

    __IOM uint32_t Capabilities[2];     /* Offset: 0x040 (RW) */
    __IOM uint32_t MaxCurrentCaps[2];   /* Offset: 0x048 (RW) */

    __IOM uint16_t ForceEventAutoCmd;   /* Offset: 0x050 (RW) */
    __IOM uint16_t ForceEventErrStatus; /* Offset: 0x052 (RW) */

    __IOM uint8_t AdmaErrStatus;        /* Offset: 0x054 (RW) */
    uint8_t rsvd1[3];

    __IOM uint32_t AdmaAddr[2];         /* Offset: 0x058 (RW) */
    uint16_t rsvd2[67];

    __IOM uint16_t PointerEmbedded;     /* Offset: 0x0E6 (RW) */
    __IOM uint16_t PointerVendor;       /* Offset: 0x0E8 (RW) */
    uint16_t rsvd3[8];

    __IOM uint16_t SoftIntStatus;       /* Offset: 0x0FC (RW) */
    __IOM uint16_t HostVersion;         /* Offset: 0x0FE (RW) */

} cvi_sdhc_regs_t;



struct cvi_dev_in_endp {
    __IOM uint32_t DIEPCTL;               /* Control Register */
    uint32_t res1;
    __IOM uint32_t DIEPINT;               /* Interrupt Register */
    uint32_t res2;
    __IOM uint32_t DIEPTSIZ;              /* Transfer Size Register */
    __IOM uint32_t DIEPDMA;               /* DMA Address Register */
    __IOM uint32_t DTXFSTS;               /* Transmit FIFO Status Register */
    __IOM uint32_t DIEPDMAB;              /* Buffer Address Register */
};


struct cvi_dev_out_endp {
    __IOM uint32_t DOEPCTL;               /* Control Register */
    uint32_t res1;
    __IOM uint32_t DOEPINT;               /* Interrupt Register */
    uint32_t res2;
    __IOM uint32_t DOEPTSIZ;              /* Transfer Size Register */
    __IOM uint32_t DOEPDMA;               /* DMA Address Register */
    uint32_t res3;
    __IOM uint32_t DOEPDMAB;              /* Buffer Address Register */
};


typedef struct {

    __IOM uint32_t GOTGCTL;             /* 0x000 (RW) : */
    __IOM uint32_t GOTGINT;             /* 0x004 (RW) : */
    
    __IOM uint32_t GAHBCFG;             /* 0x000 (RW) : */
    __IOM uint32_t GUSBCFG;             /* 0x000 (RW) : */
    
    __IOM uint32_t GRSTCTL;             /* 0x000 (RW) : */
    __IOM uint32_t GINTSTS;             /* 0x000 (RW) : */
    __IOM uint32_t GINTMSK;             /* 0x000 (RW) : */
    
    __IOM uint32_t GRXSTSR;             /* 0x000 (RW) : */
    __IOM uint32_t GRXSTSP;             /* 0x000 (RW) : */
    
    __IOM uint32_t GRXFSIZ;             /* 0x000 (RW) : */
    __IOM uint32_t GNPTXFSIZ;           /* 0x000 (RW) : */
    __IOM uint32_t GNPTXSTS;            /* 0x000 (RW) : */
    
    __IOM uint32_t GI2CCTL;             /* 0x000 (RW) : */
    __IOM uint32_t GPVNDCTL;            /* 0x000 (RW) : */
    __IOM uint32_t GGPIO;               /* 0x000 (RW) : */
    __IOM uint32_t GUID;                /* 0x000 (RW) : */
    __IOM uint32_t GSNPSID;             /* 0x040 (RW) : */
    
    __IOM uint32_t GHWCFG1;             /* 0x044 (RW) : */
    __IOM uint32_t GHWCFG2;             /* 0x048 (RW) : */
    __IOM uint32_t GHWCFG3;             /* 0x04C (RW) : */
    __IOM uint32_t GHWCFG4;             /* 0x050 (RW) : */
    __IOM uint32_t GLPMCFG;             /* 0x054 (RW) : */
    
    __IOM uint32_t GPWRDN;              /* 0x058 (RW) : */
    __IOM uint32_t GDFIFOCFG;           /* 0x05C (RW) : */
    __IOM uint32_t GADPCTL;             /* 0x060 (RW) : */
    __IOM uint32_t GREFCLK;             /* 0x064 (RW) : */
    __IOM uint32_t GINTMSK2;            /* 0x068 (RW) : */
    __IOM uint32_t GINTSTS2;            /* 0x06C (RW) : */
    uint32_t rsvd1[36];

    __IOM uint32_t HPTXFSIZ;            /* 0x100 (RW) : Host Periodic Transmit FIFO Size Register */
    __IOM uint32_t DIEPTXF[15];         /* 0x104 (RW) : Device IN Endpoint Transmit FIFO Size Register */
    uint32_t rsvd2[432];
    
    
    __IOM uint32_t DCFG;                /* 0x800 (RW) : */
    __IOM uint32_t DCTL;                /* 0x804 (RW) : */
    __IOM uint32_t DSTS;                /* 0x808 (RW) : */
    uint32_t rsvd3;
    
    __IOM uint32_t DIEPMSK;             /* 0x810 (RW) : */
    __IOM uint32_t DOEPMSK;             /* 0x814 (RW) : */
    __IOM uint32_t DAINT;               /* 0x818 (RW) : */
    __IOM uint32_t DAINTMSK;            /* 0x81C (RW) : */
    uint32_t rsvd4[2];

    __IOM uint32_t DVBUSDIS;            /* 0x828 (RW) : */
    __IOM uint32_t DVBUSPULSE;          /* 0x82C (RW) : */
    __IOM uint32_t DTHRCTL;             /* 0x830 (RW) : */
    __IOM uint32_t DIEPEMPMSK;          /* 0x834 (RW) : Device IN Endpoint FIFO Empty Interrupt Mask Register */
    uint32_t rsvd5[50];

    struct cvi_dev_in_endp in_endp[16];     /* 0x900 (RW) : */
    struct cvi_dev_out_endp out_endp[16];   /* 0xB00 (RW) : */
    uint32_t rsvd6[64];

    __IOM uint32_t PCGCCTL;             /* 0xE00 (RW) : */
    __IOM uint32_t PCGCCTL1;            /* 0xE04 (RW) : */

    /* 0x01000 : DFIFO push/pop */
    /* 0x20000 : DFIFO debug read/write */

} cvi_usb_regs_t;





#define BIT_SPI_INT_TRAN_DONE                (0x01 << 0)
#define BIT_SPI_INT_RD_FIFO                  (0x01 << 2)
#define BIT_SPI_INT_WR_FIFO                  (0x01 << 3)
#define BIT_SPI_INT_RX_FRAME                 (0x01 << 4)
#define BIT_SPI_INT_TX_FRAME                 (0x01 << 5)



typedef struct {

    __IOM uint32_t SPI_CTRL;            /* 0x000 (RW) : clock div */
    __IOM uint32_t CE_CTRL;             /* 0x004 (RW) : CE operation control */
    __IOM uint32_t DLY_CTRL;            /* 0x008 (RW) : delay control */
    __IOM uint32_t DMMR_CTRL;           /* 0x00C (RW) : direct memory read */
    
    __IOM uint32_t TRAN_CSR;            /* 0x010 (RW) : trans control */
    __IOM uint32_t TRAN_NUM;            /* 0x014 (RW) : num of data frames */
    
    union {
        __IOM uint32_t FF32;            /* 0x018 (RW) : fifo port, read or write */
        __IOM uint16_t FF16;
        __IOM uint8_t FF8;
    };

    uint32_t rsvd1;

    __IOM uint32_t FIFO_PT;             /* 0x020 (RW) : */
    uint32_t rsvd2;
    __IOM uint32_t INT_STS;             /* 0x028 (RW) : */
    __IOM uint32_t INT_EN;              /* 0x02C (RW) : */

} cvi_spinor_regs_t;



typedef struct {

    __IOM uint32_t CLK_EN[5];           /* 0x000 (RW) : */
    uint32_t rsvd1[3];

    __IOM uint32_t CLK_SEL;             /* 0x020 (RW) : */
    uint32_t rsvd2[3];

    __IOM uint32_t CLK_BYP[2];          /* 0x030 (RW) : */
    uint32_t rsvd3[2];

    __IOM uint32_t DIV_A53_A0;          /* 0x040 (RW) : A53-0 */
    __IOM uint32_t DIV_A53_A1;          /* 0x044 (RW) : A53-1 */
    __IOM uint32_t DIV_CPU_AXI0;        /* 0x048 (RW) : */
    uint32_t rsvd4;

    __IOM uint32_t DIV_CPU_GIC;         /* 0x050 (RW) : A53, GIC */
    __IOM uint32_t DIV_TPU;             /* 0x054 (RW) : */
    uint32_t rsvd5[3];

    __IOM uint32_t DIV_EMMC;            /* 0x064 (RW) : */
    uint32_t rsvd6;
    __IOM uint32_t DIV_EMMC_100K;       /* 0x06C (RW) : */

    __IOM uint32_t DIV_SD0;             /* 0x070 (RW) : */
    uint32_t rsvd7;
    __IOM uint32_t DIV_SD0_100K;        /* 0x078 (RW) : */

    __IOM uint32_t DIV_SD1;             /* 0x07C (RW) : */
    uint32_t rsvd8;
    __IOM uint32_t DIV_SD1_100K;        /* 0x084 (RW) : */

    __IOM uint32_t DIV_SPI_NAND;        /* 0x088 (RW) : */
    __IOM uint32_t DIV_ETH_500M;        /* 0x08C (RW) : */
    uint32_t rsvd9;
    __IOM uint32_t DIV_GPIO_DB;         /* 0x094 (RW) : */

    __IOM uint32_t DIV_SDMA_AUD[4];     /* 0x098 (RW) : */
    __IOM uint32_t DIV_CAM_200;         /* 0x0A8 (RW) : */
    uint32_t rsvd10[3];

    __IOM uint32_t DIV_AXI4;            /* 0x0B8 (RW) : */
    __IOM uint32_t DIV_AXI6;            /* 0x0BC (RW) : */
    uint32_t rsvd11;

    __IOM uint32_t DIV_DSI_ESC;         /* 0x0C4 (RW) : */
    __IOM uint32_t DIV_AXI_VIP;         /* 0x0C8 (RW) : */
    uint32_t rsvd20;

    __IOM uint32_t DIV_SRC_VIP_SYS0;    /* 0x0D0 (RW) : */
    uint32_t rsvd12;
    __IOM uint32_t DIV_SRC_VIP_SYS1;    /* 0x0D8 (RW) : */
    uint32_t rsvd13;

    __IOM uint32_t DIV_DISP_SRC_VIP;    /* 0x0E0 (RW) :  */
    __IOM uint32_t DIV_AXI_VC;          /* 0x0E4 (RW) : video codec */
    uint32_t rsvd14;
    __IOM uint32_t DIV_VC_SRC;          /* 0x0EC (RW) : */
    uint32_t rsvd15[3];

    __IOM uint32_t DIV_1M;              /* 0x0FC (RW) : */
    __IOM uint32_t DIV_SPI;             /* 0x100 (RW) : */
    __IOM uint32_t DIV_I2C;             /* 0x104 (RW) : */
    uint32_t rsvd16[2];

    __IOM uint32_t DIV_SRC_VIP_SYS2;    /* 0x110 (RW) : */
    uint32_t rsvd17;
    
    __IOM uint32_t DIV_AUD_SRC;         /* 0x118 (RW) : */
    uint32_t rsvd18;

    __IOM uint32_t DIV_PWM_SRC;         /* 0x120 (RW) : */
    uint32_t rsvd19;

    __IOM uint32_t DIV_AP_DBG;          /* 0x128 (RW) : */
    __IOM uint32_t DIV_RTCSYS_SRC;      /* 0x12C (RW) : */

    __IOM uint32_t DIV_C906_B0;         /* 0x130 (RW) : */
    __IOM uint32_t DIV_C906_B1;         /* 0x134 (RW) : */
    __IOM uint32_t DIV_C906_C0;         /* 0x138 (RW) : */
    __IOM uint32_t DIV_C906_C1;         /* 0x13C (RW) : */

    __IOM uint32_t DIV_SRC_VIP_SYS3;    /* 0x140 (RW) : */
    __IOM uint32_t DIV_SRC_VIP_SYS4;    /* 0x144 (RW) : */

} clk_div_regs_t;




typedef struct {
    __IOM uint32_t TLC;                 /* Offset: 0x000 (R/W) TimerLoadCount */
    __IM  uint32_t TCV;                 /* Offset: 0x004 (R/ ) TimerCurrentValue */
    __IOM uint32_t TCR;                 /* Offset: 0x008 (R/W) TimerControlReg */
    __IM  uint32_t TEOI;                /* Offset: 0x00c (R/ ) TimerEOI */
    __IM  uint32_t TIS;                 /* Offset: 0x010 (R/ ) TimerIntStatus */
} dw_timer_regs_t;


typedef struct {
    __IM  uint32_t TSIS;                /* Offset: 0x0A0 (R/ ) TimersIntStatus */
    __IM  uint32_t TSEOI;               /* Offset: 0x0A4 (R/ ) TimersEOI */
    __IM  uint32_t TSRIS;               /* Offset: 0x0A8 (R/ ) TimersRawIntStatus */
    __IM  uint32_t VERN;                /* Offset: 0x0AC (R/ ) Version, 2.10a */
} dw_timer_general_regs_t;





typedef struct {
    __IOM uint32_t IC_CON;                    /* Offset: 0x000 (R/W)  I2C Control */
    __IOM uint32_t IC_TAR;                    /* Offset: 0x004 (R/W)  I2C target address */
    __IOM uint32_t IC_SAR;                    /* Offset: 0x008 (R/W)  I2C slave address  */
    __IOM uint32_t IC_HS_MADDR;               /* Offset: 0x00C (R/W)  I2C HS Master Mode Code Address */
    __IOM uint32_t IC_DATA_CMD;               /* Offset: 0x010 (R/W)  I2C RX/TX Data Buffer and Command */
    __IOM uint32_t IC_SS_SCL_HCNT;            /* Offset: 0x014 (R/W)  Standard speed I2C Clock SCL High Count */
    __IOM uint32_t IC_SS_SCL_LCNT;            /* Offset: 0x018 (R/W)  Standard speed I2C Clock SCL Low Count */
    __IOM uint32_t IC_FS_SCL_HCNT;            /* Offset: 0x01C (R/W)  Fast speed I2C Clock SCL High Count */
    __IOM uint32_t IC_FS_SCL_LCNT;            /* Offset: 0x020 (R/W)  Fast speed I2C Clock SCL Low Count */
    __IOM uint32_t IC_HS_SCL_HCNT;            /* Offset: 0x024 (R/W)  High speed I2C Clock SCL High Count*/
    __IOM uint32_t IC_HS_SCL_LCNT;            /* Offset: 0x028 (R/W)  High speed I2C Clock SCL Low Count */
    __IM  uint32_t IC_INTR_STAT;              /* Offset: 0x02C (R)    I2C Interrupt Status */
    __IOM uint32_t IC_INTR_MASK;              /* Offset: 0x030 (R/W)  I2C Interrupt Mask */
    __IM  uint32_t IC_RAW_INTR_STAT;          /* Offset: 0x034 (R)    I2C Raw Interrupt Status */
    __IOM uint32_t IC_RX_TL;                  /* Offset: 0x038 (R/W)  I2C Receive FIFO Threshold */
    __IOM uint32_t IC_TX_TL;                  /* Offset: 0x03C (R/W)  I2C Transmit FIFO Threshold */
    __IM  uint32_t IC_CLR_INTR;               /* Offset: 0x040 (R)    Clear combined and individual interrupts*/
    __IM  uint32_t IC_CLR_RX_UNDER;           /* Offset: 0x044 (R)    I2C Clear RX_UNDER interrupt  */
    __IM  uint32_t IC_CLR_RX_OVER;            /* Offset: 0x048 (R)    I2C Clear RX_OVER interrupt  */
    __IM  uint32_t IC_CLR_TX_OVER;            /* Offset: 0x04C (R)    I2C Clear TX_OVER interrupt  */
    __IM  uint32_t IC_CLR_RD_REQ;             /* Offset: 0x050 (R)    I2C Clear RD_REQ interrupt  */
    __IM  uint32_t IC_CLR_TX_ABRT;            /* Offset: 0x054 (R)    I2C Clear TX_ABRT interrupt  */
    __IM  uint32_t IC_CLR_RX_DONE;            /* Offset: 0x058 (R)    I2C Clear RX_DONE interrupt  */
    __IM  uint32_t IC_CLR_ACTIVITY;           /* Offset: 0x05C (R)    I2C Clear ACTIVITY interrupt  */
    __IM  uint32_t IC_CLR_STOP_DET;           /* Offset: 0x060 (R)    I2C Clear STOP_DET interrupt  */
    __IM  uint32_t IC_CLR_START_DET;          /* Offset: 0x064 (R)    I2C Clear START_DET interrupt  */
    __IM  uint32_t IC_CLR_GEN_CALL;           /* Offset: 0x068 (R)    I2C Clear GEN_CAL interrupt  */
    __IOM uint32_t IC_ENABLE;                 /* Offset: 0x06C (R/W)  I2C enable */
    __IM  uint32_t IC_STATUS;                 /* Offset: 0x070 (R)    I2C status register */
    __IM  uint32_t IC_TXFLR;                  /* Offset: 0x074 (R)    Transmit FIFO Level register */
    __IM  uint32_t IC_RXFLR;                  /* Offset: 0x078 (R)    Receive FIFO Level Register */
    
    __IOM uint32_t IC_SDA_HOLD;               /* Offset: 0x07C (R/W)  */
    __IOM uint32_t IC_TX_ABRT_SOURCE;         /* Offset: 0x080 (R/W)  */
    __IOM uint32_t IC_SLV_DATA_NACK_ONLY;     /* Offset: 0x084 (R/W)  */
    __IOM uint32_t IC_DMA_CR;                 /* Offset: 0x088 (R/W)  DMA Control Register for transmit and receive handshaking interface  */
    __IOM uint32_t IC_DMA_TDLR;               /* Offset: 0x08C (R/W)  DMA Transmit Data Level */
    __IOM uint32_t IC_DMA_RDLR;               /* Offset: 0x090 (R/W)  DMA Receive Data Level */
    __IOM uint32_t IC_SDA_SETUP;              /* Offset: 0x094 (R/W)  SDA Setup register */
    __IOM uint32_t IC_ACK_GENERAL_CALL;       /* Offset: 0x098 (R/W)  ACK General Call Register */
    __IOM uint32_t IC_ENABLE_STATUS;          /* Offset: 0x09C (R/W)  enable status register */
    __IOM uint32_t IC_FS_SPKLEN;              /* Offset: 0x0A0 (R/W)  SS and FS spike suppression limit */
    __IOM uint32_t IC_HS_SPKLEN;              /* Offset: 0x0A4 (R/W)  HS spike suppression limit */
    __IM  uint32_t IC_CLR_RESTART_DET;        /* Offset: 0x0A8 (R/W)  clear RESTART_DET interrupt */
    
} dw_iic_regs_t;




static inline void  test_sleep( uint32_t ticks )
{
    for ( uint32_t i=0; i<ticks; i++ )  {
        asm volatile ( "nop" );
    }
}



/* pad mux base : 0x0300_1000 */

#define PAD_MUX_12  0x300101C       // SD0_PWR_EN
#define PAD_MUX_14  0x3001020       // SPK_EN
#define PAD_MUX_15  0x3001024       // UART0_TX
#define PAD_MUX_16  0x3001028       // UART0_RX
#define PAD_MUX_17  0x300102C       // SPINOR_HOLD_X
#define PAD_MUX_18  0x3001030       // SPINOR_SCK
#define PAD_MUX_19  0x3001034       // SPINOR_MOSI
#define PAD_MUX_20  0x3001038       // SPINOR_WP_X
#define PAD_MUX_21  0x300103C       // SPINOR_MISO
#define PAD_MUX_22  0x3001040       // SPINOR_CS_X

#define PAD_MUX_23  0x300104C       // IIC0_SCL
#define PAD_MUX_24  0x3001050       // IIC0_SDA

#define PAD_MUX_31  0x3001068       // PWR_SEQ2
#define PAD_MUX_35  0x3001088       // SD1_GPIO0
#define PAD_MUX_36  0x3001084       // SD1_GPIO1
#define PAD_MUX_38  0x300108C       // SD1_D3
#define PAD_MUX_39  0x3001090       // SD1_D2
#define PAD_MUX_40  0x3001094       // SD1_D1
#define PAD_MUX_41  0x3001098       // SD1_D0
#define PAD_MUX_42  0x300109C       // SD1_CMD
#define PAD_MUX_43  0x30010A0       // SD1_CLK

#define PAD_MUX_44  0x30010A8       // ADC1
#define PAD_MUX_45  0x30010AC       // USB_VBUS_DET

#define PAD_MUX_47  0x30010C0       // ETH_TXP
#define PAD_MUX_48  0x30010C4       // ETH_TXM
#define PAD_MUX_49  0x30010C8       // ETH_RXP
#define PAD_MUX_50  0x30010CC       // ETH_RXM

#define PAD_MUX_56  0x30010D4       // MIPIRX4N
#define PAD_MUX_57  0x30010D8       // MIPIRX4P
#define PAD_MUX_58  0x30010DC       // MIPIRX3N
#define PAD_MUX_59  0x30010E0       // MIPIRX3P
#define PAD_MUX_60  0x30010E4       // MIPIRX2N
#define PAD_MUX_61  0x30010E8       // MIPIRX2P
#define PAD_MUX_62  0x30010EC       // MIPIRX1N
#define PAD_MUX_63  0x30010F0       // MIPIRX1P
#define PAD_MUX_64  0x30010F4       // MIPIRX0N
#define PAD_MUX_65  0x30010F8       // MIPIRX0P


#define PAD_MUX_67  0x3001120       // GPIOC[23], AUD_AINL_MIC, 
#define PAD_MUX_1   0x300112C       // GPIOC[24], AUD_AOUTR, 



/* IOBLK_G7, ioType = 18OD33,  PowerDomain = VDDIO_SD0_SPI */
#define PAD_CTL_12  0x3001904       // SD0_PWR_EN
#define PAD_CTL_14  0x3001908       // SPK_EN
#define PAD_CTL_15  0x300190C       // UART0_TX
#define PAD_CTL_16  0x3001910       // UART0_RX

#define PAD_CTL_17  0x3001914       // SPINOR_HOLD_X
#define PAD_CTL_18  0x3001918       // SPINOR_SCK
#define PAD_CTL_19  0x300191C       // SPINOR_MOSI
#define PAD_CTL_20  0x3001920       // SPINOR_WP_X
#define PAD_CTL_21  0x3001924       // SPINOR_MISO
#define PAD_CTL_22  0x3001928       // SPINOR_CS_X

#define PAD_CTL_23  0x3001934       // IIC0_SCL
#define PAD_CTL_24  0x3001938       // IIC0_SDA

/* IOBLK_GRTC, ioType=1.8V_IO, PowerDomain = VDDIO_RTC  */
#define PAD_CTL_31  0x5027010       // PWR_SEQ2

/* IOBLK_GRTC, ioType=18OD33, PowerDomain=VDD33A_ETH_USB_SD1 */
#define PAD_CTL_35  0x5027034       // SD1_GPIO0
#define PAD_CTL_36  0x5027030       // SD1_GPIO1
#define PAD_CTL_38  0x5027038       // SD1_D3
#define PAD_CTL_39  0x502703C       // SD1_D2
#define PAD_CTL_40  0x5027040       // SD1_D1
#define PAD_CTL_41  0x5027044       // SD1_D0
#define PAD_CTL_42  0x5027048       // SD1_CMD
#define PAD_CTL_43  0x502704C       // SD1_CLK

/* IOBLK_G1, ioType=1.8V_IO, PowerDomain=VDD18A_USB_PLL_ETH_CSI  */
#define PAD_CTL_44  0x3001804    // ADC1
#define PAD_CTL_45  0x3001808    // USB_VBUS_DET

/* IOBLK_G12, ioType=ETH_GPIO, PowerDomain=VDD18A_USB_PLL_ETH_CSI */
/*
PAD_CTL_47
PAD_CTL_48
PAD_CTL_49
PAD_CTL_50
*/

/* IOBLK_G12, ioType=1.8V_IO, PowerDomain=VDD18A_USB_PLL_ETH_CSI */
#define PAD_CTL_56  0x3001C04       // MIPIRX4N
#define PAD_CTL_57  0x3001C08       // MIPIRX4P
#define PAD_CTL_58  0x3001C0C       // MIPIRX3N
#define PAD_CTL_59  0x3001C10       // MIPIRX3P
#define PAD_CTL_60  0x3001C14       // MIPIRX2N
#define PAD_CTL_61  0x3001C18       // MIPIRX2P
#define PAD_CTL_62  0x3001C1C       // MIPIRX1N
#define PAD_CTL_63  0x3001C20       // MIPIRX1P
#define PAD_CTL_64  0x3001C24       // MIPIRX0N
#define PAD_CTL_65  0x3001C28       // MIPIRX0P




static inline uint32_t read_reg( uintptr_t addr )
{
    return (*((volatile uint32_t *) (addr)));
}


static inline void write_reg( uintptr_t addr, uint32_t value )
{
    *(volatile uint32_t *)(addr) = value;
    return;
}




#define RTC_EN_PWR_WAKEUP       0xBC
#define RTC_EN_SHDN_REQ         0xC0
#define RTC_EN_PWR_CYC_REQ      0xC8
#define RTC_EN_WARM_RST_REQ     0xCC
#define RTC_EN_WDT_RST_REQ      0xE0
#define RTC_EN_SUSPEND_REQ      0xE4


#define RTC_CTRL0_UNLOCKKEY     0x4
#define RTC_CTRL0               0x8
#define RTC_CTRL0_STATUS0       0xC





#endif


